package com.probiz.estore.core.controller;

import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;

import com.opensymphony.oscache.util.StringUtil;
import com.probiz.estore.core.model.BaseObject;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.service.GenericManager;
import com.probiz.estore.core.util.ContextUtil;
import com.probiz.estore.webapp.util.RequestContext;
import com.probiz.estore.webapp.util.RequestUtil;

/**
 * 只用于前台的Controller基类
 * 
 * @param <T>
 */
public abstract class GenericStoreFrontController<T> extends BaseController {

    /**
     * 缺省每页显示多少条记录，子类可在配置文件根据需要设置。缺省10。
     */
    protected int defaultPageSize = 10;

    protected GenericManager<T> mgr;


    /**
     * When action parameter is not used/presented. decide view by parsing the
     * page name from URL.
     * 
     * @param req
     * @param resp
     * @return
     * @throws ServletException
     */
    public ModelAndView defaultAction(HttpServletRequest req, HttpServletResponse resp)
    {
        String page = RequestUtil.getRequestedPageName(req, getDefaultViewName());
        return getModelAndView(page, null);
    }
    
    /**
     * 创建SearchCriteria
     * @param request
     * @param filterHqlName
     * @return
     */
    protected SearchCriteria createSearchCriteria(HttpServletRequest request, Object[] initHqlParamValues) {
		return createSearchCriteria(request, BaseObject.FilterHqlName.DEFAULT, initHqlParamValues);
	}
    
    protected SearchCriteria createSearchCriteria(HttpServletRequest request, Enum filterHqlName) {
		return createSearchCriteria(request, filterHqlName, null);
	}
    
    protected SearchCriteria createSearchCriteria(HttpServletRequest request) {
		return createSearchCriteria(request, null, null);
	}

    /**
     * 创建SearchCriteria
     * @param request
     * @param filterHqlName
     * @param initHqlParamValues
     * @return
     */
    protected SearchCriteria createSearchCriteria(HttpServletRequest request, Enum filterHqlName,Object[] initHqlParamValues)
    {
        SearchCriteria sc = mgr.getSearchCriteriaBuilder(filterHqlName==null?BaseObject.FilterHqlName.DEFAULT:filterHqlName,initHqlParamValues).buildSearchCriteria(request, defaultPageSize);
        // storeFront的SearchCriteria是不会被保存到session中
        // 页面层需要用request（而不是session）里面的sc进行绑定（需要绑定column，filter，order等）
        request.setAttribute("sc", sc);
        return sc;
    }
    
    /**
     * 返回查询的list对象。
     * @param sc
     * @return
     */
    protected List searchByCriteria(SearchCriteria sc) {
        if (sc.getPageNo() < 1)  //如果是翻页过前，就拿第一页就可以。
        {
            sc.changePaging(1, sc.getPageSize());
        }
        List result = mgr.searchByCriteria(sc);
        if (result == null|| result.size() == 0 )
        {
            if (sc.getPageNo() > sc.getTotalPageCount()) //如果是翻页前，就拿最后一页就可以。
            {
                sc.changePaging(sc.getTotalPageCount(), sc.getPageSize());
                result = mgr.searchByCriteria(sc);
            }
        }
        return result;
    }

    /**
     * can override this
     * 
     * @return
     */
    protected String getDefaultViewName()
    {
        return "index";
    }


    /**
     * 简化版本， 适用于不支持动态配置模版并且不需要传入Model的时候用。需要保证templatePath存在。
     * 
     * @param templatePath
     * @return
     */
    protected ModelAndView getModelAndView(final String templatePath)
    {
        return getModelAndView(templatePath, null, null);
    }
    
    /**
     * TODO,未完善，未测试，性能优化（如缓存）
     * 
     * @param templatePath     不能用/开头
     * @param defaultTemplatePath    没有指定模版，或指定的模版找不到的时候，使用的缺省模版
     * @param model
     * @return
     */
    protected ModelAndView getModelAndView(final String in_templatePath, final String defaultTemplatePath,
                    final Map model)
    {
        String templatePath = getTemplatePath(defaultTemplatePath, in_templatePath);
        return templatePath == null ? null : new ModelAndView(templatePath, model);
    }
    
    /**
     * TODO,未完善，未测试，性能优化（如缓存）
     * 
     * @param defaultTemplate   没有指定模版，或指定的模版找不到的时候，使用的缺省模版
     * @param templatePath
     * @return
     */
    protected String getTemplatePath(String defaultTemplate, String templatePath)
    {
        // TODO 这个是否存在的检查应该缓存；另外，这样ViewResolver不再用检查是否存在了？
        if (StringUtil.isEmpty(templatePath) || !isTemplateExists(templatePath))
        {
            
            //logger.debugger("Template not found for page: [" + templatePath + "].");
            return defaultTemplate;
        }
        return templatePath;
    }

    protected boolean isTemplateExists(String templatePath)
    {
        return ContextUtil.getInstance().isFileExists(RequestContext.getRelativeTemplatePath(templatePath));
    }

    /**
     * 子类需要重载这个方法来实现初始化，包括设置范型mgr
     * 
     */
    protected abstract void initController() throws Exception;
    

    public void setDefaultPageSize(int avalue)
    {
        defaultPageSize = avalue;
    }
}
